package com.springboot.springautowired.javaDesignModel.proxyModel;

/**
 * 静态代理
 *   代理模式三要素
 *      抽象主题
 *      被代理对象--实现抽象主题，定义自己的业务逻辑操作
 *      代理对象--实现抽象主题并且有被代理对象的引用，控制被代理对象的创建，并且还有自己的业务实现
 * @author mac
 * @date 2021/9/17 10:43 上午
 */
public class StaticProxy {
    public static void main(String[] args) {
        Operation.operation2();
    }
}

interface Subject {
    public void movie();
}

/**
 * 被代理对象
 */
class Star implements Subject {
    @Override
    public void movie() {
        System.out.println(getClass().getSimpleName() + "：经纪人接了一部电影，我负责拍就好");
    }
}

/**
 * 代理对象
 */
class Agent implements Subject {
    private Subject star;

    public Agent(Subject star) {
        this.star = star;
    }

    @Override
    public void movie() {
        System.out.println(getClass().getSimpleName() + "：剧本很好，这部电影接下了");
        star.movie();
    }
}

interface Subject1 {
    public void movie();

    // 指定代理
    public Subject1 getAgent();
}

class Star1 implements Subject1 {
    @Override
    public void movie() {
        System.out.println(getClass().getSimpleName() + "：经纪人接了一部电影，我负责拍就好");
    }

    @Override
    public Subject1 getAgent() {
        return new Agent1(this);
    }
}

class Agent1 implements Subject1 {
    private Subject1 star;

    public Agent1(Subject1 star) {
        this.star = star;
    }

    @Override
    public void movie() {
        System.out.println(getClass().getSimpleName() + "：剧本题材很好，这部电影接下了");
        star.movie();
    }

    @Override
    public Subject1 getAgent() {
        return this;
    }
}

class Operation {
    //以下是静态代理模式下访问被代理对象的两种方式
    /**
     * 通过代理对象访问被代理对象
     */
    public static void operation1(){
        Subject star = new Star();
        Agent agent = new Agent(star);
        agent.movie();
    }

    /**
     * 通过被代理对象直接指定代理对象，然后通过代理对象访问被代理对象
     */
    public static void operation2(){
        Subject1 star = new Star1();
        Subject1 agent = star.getAgent();
        agent.movie();
    }
}
